From 396acf3bbbe00a192cb0ea0a9ccf91b1d8d2850b Mon Sep 17 00:00:00 2001
From: Fuwn <50817549+Fuwn@users.noreply.github.com>
Date: Sat, 24 Jan 2026 13:09:50 +0000
Subject: Initial commit

Created from https://vercel.com/new
---
 .../websites/[websiteId]/(reports)/goals/Goal.tsx  | 99 ++++++++++++++++++++++
 1 file changed, 99 insertions(+)
 create mode 100644 src/app/(main)/websites/[websiteId]/(reports)/goals/Goal.tsx

(limited to 'src/app/(main)/websites/[websiteId]/(reports)/goals/Goal.tsx')

diff --git a/src/app/(main)/websites/[websiteId]/(reports)/goals/Goal.tsx b/src/app/(main)/websites/[websiteId]/(reports)/goals/Goal.tsx
new file mode 100644
index 0000000..b6c4a11
--- /dev/null
+++ b/src/app/(main)/websites/[websiteId]/(reports)/goals/Goal.tsx
@@ -0,0 +1,99 @@
+import { Column, Dialog, Grid, Icon, ProgressBar, Row, Text } from '@umami/react-zen';
+import { LoadingPanel } from '@/components/common/LoadingPanel';
+import { useMessages, useResultQuery } from '@/components/hooks';
+import { File, User } from '@/components/icons';
+import { ReportEditButton } from '@/components/input/ReportEditButton';
+import { Lightning } from '@/components/svg';
+import { formatLongNumber } from '@/lib/format';
+import { GoalEditForm } from './GoalEditForm';
+
+export interface GoalProps {
+  id: string;
+  name: string;
+  type: string;
+  parameters: {
+    name: string;
+    type: string;
+    value: string;
+  };
+  websiteId: string;
+  startDate: Date;
+  endDate: Date;
+}
+
+export type GoalData = { num: number; total: number };
+
+export function Goal({ id, name, type, parameters, websiteId, startDate, endDate }: GoalProps) {
+  const { formatMessage, labels } = useMessages();
+  const { data, error, isLoading, isFetching } = useResultQuery<GoalData>(type, {
+    websiteId,
+    startDate,
+    endDate,
+    ...parameters,
+  });
+  const isPage = parameters?.type === 'path';
+
+  return (
+    <LoadingPanel data={data} isLoading={isLoading} isFetching={isFetching} error={error}>
+      {data && (
+        <Grid gap>
+          <Grid columns="1fr auto" gap>
+            <Column gap>
+              <Row>
+                <Text size="4" weight="bold">
+                  {name}
+                </Text>
+              </Row>
+            </Column>
+            <Column>
+              <ReportEditButton id={id} name={name} type={type}>
+                {({ close }) => {
+                  return (
+                    <Dialog
+                      title={formatMessage(labels.goal)}
+                      variant="modal"
+                      style={{ minHeight: 300, minWidth: 400 }}
+                    >
+                      <GoalEditForm id={id} websiteId={websiteId} onClose={close} />
+                    </Dialog>
+                  );
+                }}
+              </ReportEditButton>
+            </Column>
+          </Grid>
+          <Row alignItems="center" justifyContent="space-between" gap>
+            <Text color="muted">
+              {formatMessage(isPage ? labels.viewedPage : labels.triggeredEvent)}
+            </Text>
+            <Text color="muted">{formatMessage(labels.conversionRate)}</Text>
+          </Row>
+          <Row alignItems="center" justifyContent="space-between" gap>
+            <Row alignItems="center" gap>
+              <Icon>{parameters.type === 'path' ? <File /> : <Lightning />}</Icon>
+              <Text>{parameters.value}</Text>
+            </Row>
+            <Row alignItems="center" gap>
+              <Icon>
+                <User />
+              </Icon>
+              <Text title={`${data?.num} / ${data?.total}`}>{`${formatLongNumber(
+                data?.num,
+              )} / ${formatLongNumber(data?.total)}`}</Text>
+            </Row>
+          </Row>
+          <Row alignItems="center" gap="6">
+            <ProgressBar
+              value={data?.num || 0}
+              minValue={0}
+              maxValue={data?.total || 1}
+              style={{ width: '100%' }}
+            />
+            <Text weight="bold" size="7">
+              {data?.total ? Math.round((+data?.num / +data?.total) * 100) : '0'}%
+            </Text>
+          </Row>
+        </Grid>
+      )}
+    </LoadingPanel>
+  );
+}
-- 
cgit v1.2.3

